package com.example.srm.auth.intercept;

import com.example.srm.auth.anno.Authority;
import com.example.srm.constant.PermissionConstant;
import com.example.srm.domain.vo.Result;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.crypto.hash.Md5Hash;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.List;

/**
 * @author pfk
 * @creatTime 2021/12/08 09:17
 * @describe    AOP切面类【实现权限控制】
 */
@Component
@Aspect//标志是一个切面类
@Slf4j
public class AuthorityAspect {

    @Autowired
    private RedisTemplate redisTemplate;

    /**
     * 代表对指定注解进行增强
     * @param authority
     */
    @Pointcut("@annotation(authority)")
    public void doAuthToken(Authority authority) {}

    /**
     * 环绕处理
     * @param pjp
     * @param authority
     * @return
     * @throws Throwable
     */
    @Around("doAuthToken(authority)")
    public Object deBefore(ProceedingJoinPoint pjp, Authority authority) throws Throwable {
        System.out.println("---------方法执行之前-------------");
        //获取上下文
        RequestAttributes ra = RequestContextHolder.getRequestAttributes();
        ServletRequestAttributes sra = (ServletRequestAttributes) ra;
        HttpServletRequest request = sra.getRequest();
        HttpServletResponse response = sra.getResponse();
        try {
            Cookie userCookie = null;
            Cookie ssidCookie = null;
            for (Cookie cookie : request.getCookies()) {
                if (cookie.getName().equals("USERINFO")){
                    userCookie = cookie;
                } else if (cookie.getName().equals("SSID")){
                    ssidCookie = cookie;
                }
            }
            log.info("正在验证账号是否登录...");
            //验证账号是否登录
            String certResult = new Md5Hash(userCookie.getValue(), PermissionConstant.SECRET_KEY).toString();
            if (!certResult.equals(ssidCookie.getValue())){
                return new Result().setMsg("你还未登录~").setCode(401);
            }
            log.info("正在验证权限...");
            List<String> permissions = (List<String>) redisTemplate.opsForHash().get(PermissionConstant.USER_AUTH, userCookie.getValue());
//            for (String s : permissions) {
//                System.out.println(s);
//            }
            String[] auth = authority.auth();
            for (String s : auth) {
                if(permissions.contains(s)){
                    //放行方法
                    return pjp.proceed();
                }
            }
        }catch (NullPointerException e){
            log.error("空指针异常",e);
            return new Result().setMsg("你还未登录~").setCode(401);
        }
        return new Result().setMsg("权限不足").setCode(403);
    }



}
